﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using LyricTrackerPlugin.Properties;
using Slippor.Douban.Radio.Assist;
using System.Diagnostics;

namespace LyricTrackerPlugin
{
    public partial class LyricFrom : Form
    {
        [DllImport("user32.dll")]
        private extern static bool ReleaseCapture();
        [DllImportAttribute("user32.dll")]
        private extern static int SendMessage(IntPtr handle, int m, int p, int h);

        private readonly Timer _timer = new Timer();
        private readonly LyricTracker _tracker;
        private LyricCollection _lyrics;

        public LyricFrom(LyricTracker tracker)
        {
            _tracker = tracker;
            _timer.Tick += _timer_Tick;
            InitializeComponent();
            configControl.Closed += new EventHandler(configControl_Closed);
            this.FormClosing += LyricFrom_Closed;
            this.Load += LyricFrom_Load;
        }

        private void configControl_Closed(object sender, EventArgs e)
        {
            toolStripButtonConfig.CheckState = CheckState.Unchecked;
        }

        protected override void OnClosed(EventArgs e)
        {
            SavePosition();
            base.OnClosed(e);
        }

        private void SavePosition()
        {
            Point point;
            point = new Point(Left, Top);
            if (point.X == 0)
            {
                point.X = -1;
            }
            else if (point.Y == 0)
            {
                point.Y = -1;
            }
            _tracker.Position = point;
        }

        private void SetPosition()
        {
            Point lastPosition = _tracker.Position;
            Rectangle wokingRectangle = Screen.GetWorkingArea(this);
            if (lastPosition.X != 0 || lastPosition.Y != 0)
            {
                this.StartPosition = FormStartPosition.Manual;
                if (lastPosition.X > 0 && lastPosition.X + Width < wokingRectangle.Width)
                {
                    Left = lastPosition.X;
                }
                else if (lastPosition.X < 0)
                {
                    Left = 0;
                }
                else if (lastPosition.X + Width >= wokingRectangle.Width)
                {
                    Left = wokingRectangle.Width - Width;
                }
                if (lastPosition.Y > 0 && lastPosition.Y + Height < wokingRectangle.Height)
                {
                    Top = lastPosition.Y;
                }
                else if (lastPosition.Y < 0)
                {
                    Top = 0;
                }
                else if (lastPosition.Y + Height >= wokingRectangle.Height)
                {
                    Top = wokingRectangle.Height - Height;
                }
            }
        }
        private void LyricFrom_Load(object sender, EventArgs e)
        {
            InitShow();
        }

        private void InitShow()
        {
            toolStripButtonOnTop.CheckState = _tracker.TopMost ? CheckState.Checked : CheckState.Unchecked;
            toolStripButtonShowAll.CheckState = _tracker.ShowMode == 0 ? CheckState.Checked : CheckState.Unchecked;
            RefreshStyle();
            ChangeShowMode();
            SetPosition();
        }

        private void LyricFrom_Closed(object sender, EventArgs e)
        {
            _tracker.IsShow = false;
        }

        private void _timer_Tick(object sender, EventArgs e)
        {
            if (_lyrics != null)
            {
                var lyric = _lyrics.Next(_tracker.Elapsed);
                SetCurrentLyric(lyric);
            }
        }

        public void SetSong(Song song)
        {
            if (song != null)
            {
                if (song.Album != null && !String.IsNullOrEmpty(song.Album.ArtistString))
                {
                    var title = String.Format("{0} - {1} ", song.Title, song.Album.ArtistString);
                    if (title.Length > 64)
                    {
                        title = title.Substring(0, 64);
                    }
                    this.Text = title;
                }
                else
                {
                    this.Text = song.Title;
                }
            }
        }

        public void SetLyric(LyricCollection lyrics)
        {
            _lyrics = lyrics;
            if (_lyrics != null)
            {
                if (_lyricSwitch)
                {
                    richTextBoxLyric.Text = _lyrics.RawLyric;
                }
                else
                {
                    richTextBoxLyric.Text = _lyrics.ToString();
                }
                var lyric = _lyrics.Seek(_tracker.Elapsed);
                SetCurrentLyric(lyric);
            }
            else
            {
                richTextBoxLyric.Text = Resources.LyricFrom_NoLyric;
                textBoxLyric.Text = Resources.LyricFrom_NoLyric;
            }
        }

        private void SetCurrentLyric(Lyric lyric)
        {
            _timer.Stop();
            if (lyric != null && !this.IsDisposed)
            {
                if (_lyricSwitch)
                {
                    textBoxLyric.Text = String.Format("{0} {1}", _tracker.Elapsed, lyric.Text.Trim());
                }
                else
                {
                    SetLyricColor(0, richTextBoxLyric.Text.Length, Color.Black);
                    SetLyricColor(0, lyric.Offset, Color.Gray);
                    SetLyricColor(lyric.Offset, lyric.Text.Length, Color.Red);
                    richTextBoxLyric.Refresh();
                    richTextBoxLyric.SelectionStart = lyric.ScrollOffset;
                    richTextBoxLyric.SelectionLength = 0;
                    richTextBoxLyric.ScrollToCaret();
                    if (!String.IsNullOrEmpty(lyric.Text.Trim()))
                    {
                        textBoxLyric.Text = lyric.Text.Trim();
                    }
                    else
                    {
                        textBoxLyric.Text = @"[...Music...]";
                    }
                }
                if (_tracker.ShowMode == (int)LyricShowMode.Min)
                {
                    AdjustLyricSize();
                }
                if (lyric.Dif > 0)
                {
                    _timer.Interval = lyric.Dif;
                    _timer.Start();
                }
            }
        }

        private void AdjustLyricSize()
        {
            using (Graphics g = textBoxLyric.CreateGraphics())
            {
                SizeF s = g.MeasureString(textBoxLyric.Text, textBoxLyric.Font);
                if (s.Width > this.Width)
                {
                    this.Width = (int)s.Width + this.Width - textBoxLyric.Width;
                }
                if (this.Width > Screen.GetWorkingArea(this).Width)
                {
                    this.Width = Screen.GetWorkingArea(this).Width;
                }
            }
        }

        private void SetLyricColor(int start, int length, Color color)
        {
            richTextBoxLyric.SelectionStart = start;
            richTextBoxLyric.SelectionLength = length;
            richTextBoxLyric.SelectionColor = color;
        }

        public void Pause()
        {
            //_timer.Stop();
        }

        public void Resume()
        {
            //_timer.Stop();
        }

        public void Clear()
        {
            _lyrics = null;
            this.Text = "Lyric";
            textBoxLyric.Text = richTextBoxLyric.Text = @"[Loading...]";
        }

        bool _lyricSwitch = false;

        private void toolStripButtonReSearch_Click(object sender, EventArgs e)
        {
            Clear();
            _tracker.Research();
        }

        private void toolStripButtonOnTop_CheckedChanged(object sender, EventArgs e)
        {
            _tracker.TopMost = this.TopMost = toolStripButtonOnTop.Checked;
        }

        private void toolStripButtonShowAll_CheckStateChanged(object sender, EventArgs e)
        {
            _tracker.ShowMode = (int)(toolStripButtonShowAll.Checked ? LyricShowMode.All : LyricShowMode.Min);
            ChangeShowMode();
        }

        private void ChangeShowMode()
        {
            richTextBoxLyric.Visible = toolStripButtonConfig.Visible = toolStripButtonShowAll.Checked;
            textBoxLyric.Visible = toolStripButtonClose.Visible = toolStripButtonMove.Visible = !toolStripButtonShowAll.Checked;
            toolStripButtonShowAll.ToolTipText = toolStripButtonShowAll.Text = toolStripButtonShowAll.Checked ? "完整模式" : "简洁模式";
            this.FormBorderStyle = toolStripButtonShowAll.Checked ? FormBorderStyle.SizableToolWindow : FormBorderStyle.None;
            if (toolStripButtonShowAll.Checked)
            {
                if (this.Height <= richTextBoxLyric.Height + toolStripMenu.Height)
                {
                    this.Height = this.Height - textBoxLyric.Height + richTextBoxLyric.Height;
                }
                this.TransparencyKey = Color.Empty;
            }
            else
            {
                if (this.Height >= toolStripMenu.Height + textBoxLyric.Height)
                {
                    this.Height = this.Height - richTextBoxLyric.Height + textBoxLyric.Height;
                }
                this.TransparencyKey = this.BackColor;
                AdjustLyricSize();
            }
            textBoxLyric.BorderStyle = toolStripButtonShowAll.Checked ? BorderStyle.FixedSingle : BorderStyle.None;
        }

        private void toolStripButtonIncrease_Click(object sender, EventArgs e)
        {
            _lyrics.Just(new TimeSpan(0, 0, 0, 0, 1000));
            var lyric = _lyrics.Seek(_tracker.Elapsed);
            SetCurrentLyric(lyric);
        }

        private void toolStripButtonDecrease_Click(object sender, EventArgs e)
        {
            _lyrics.Just(new TimeSpan(0, 0, 0, 0, -1000));
            var lyric = _lyrics.Seek(_tracker.Elapsed);
            SetCurrentLyric(lyric);
        }

        private void toolStripButtonMove_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Cursor = Cursors.SizeAll;
                ReleaseCapture();
                SendMessage(this.Handle, 0xA1, 0x2, 0);
                this.Cursor = Cursors.Default;
            }
        }

        private void toolStripButtonClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        public void RefreshStyle()
        {
            if (textBoxLyric.Font != _tracker.Font)
            {
                textBoxLyric.Font = _tracker.Font;
            }
            if (textBoxLyric.ForeColor != _tracker.FontColor)
            {
                textBoxLyric.ForeColor = _tracker.FontColor;
            }
        }

        private void toolStripButtonConfig_CheckStateChanged(object sender, EventArgs e)
        {
            configControl.Visible = toolStripButtonConfig.Checked;
            configControl.BringToFront();
        }

        private void toolStripButtonSwitch_CheckStateChanged(object sender, EventArgs e)
        {
            _lyricSwitch = toolStripButtonSwitch.Checked;
            SetLyric(_lyrics);
        }
    }

    public enum LyricShowMode
    {
        All = 0,
        Min = 1,
    }
}
